#include <cstdint> 
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 
#endif
#ifndef NOMINMAX
#define NOMINMAX 
#endif
#include <windows.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 
#ifdef _MSC_VER
#pragma comment(lib, "Ws2_32.lib") 
#endif
#endif

#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>  
#include <map>

#include "crow_all.h"
#include "crow_ext.h"
#include "login_interface.h"
#include "map_service.h"
#include "database/database.h"
#include "database/place_db.h"
#include "curl_wrapper/curl_wrapper.h"
#include "global_vars.h"
#include "diary_interface.h"
#include <sqlite3.h>

// 页面模板缓存
std::map<std::string, std::string> pageTemplates;

bool ends_with(const std::string& str, const std::string& suffix) {
    if (str.length() < suffix.length()) return false;
    return str.substr(str.length() - suffix.length()) == suffix;
}

// 读取文件内容
static std::string readFile(const std::string& filepath) {
    std::ifstream file(filepath, std::ios::binary);
    if (!file) {
        return "";
    }
    
    // 获取文件大小
    file.seekg(0, std::ios::end);
    size_t size = file.tellg();
    file.seekg(0, std::ios::beg);
    
    // 读取文件内容
    std::string content(size, '\0');
    file.read(&content[0], size);
    
    return content;
}

// 从popularity_api.cpp导入的函数
double increasePopularity(int placeId) {
    sqlite3 *db;
    char *errMsg = 0;
    int rc;
    double newPopularity = 0;
    
    std::cout << "API: 增加地点 " << placeId << " 的热度" << std::endl;
    
    // 打开数据库
    rc = sqlite3_open("tour_system.db", &db);
    if (rc) {
        std::cerr << "数据库错误: " << sqlite3_errmsg(db) << std::endl;
        sqlite3_close(db);
        return -1;
    }
    
    // 步骤1: 获取当前热度
    std::string selectSql = "SELECT popularity FROM places WHERE id = " + std::to_string(placeId);
    sqlite3_stmt *stmt;
    
    rc = sqlite3_prepare_v2(db, selectSql.c_str(), -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        std::cerr << "SQL错误: " << sqlite3_errmsg(db) << std::endl;
        sqlite3_close(db);
        return -1;
    }
    
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        double currentPopularity = sqlite3_column_double(stmt, 0);
        newPopularity = currentPopularity + 0.5;
    } else {
        std::cerr << "找不到地点ID " << placeId << std::endl;
        sqlite3_finalize(stmt);
        sqlite3_close(db);
        return -1;
    }
    
    sqlite3_finalize(stmt);
    
    // 步骤2: 更新热度 (+0.5)
    std::string updateSql = "UPDATE places SET popularity = " + std::to_string(newPopularity) + 
                           " WHERE id = " + std::to_string(placeId);
    
    rc = sqlite3_exec(db, updateSql.c_str(), 0, 0, &errMsg);
    if (rc != SQLITE_OK) {
        std::cerr << "SQL错误: " << errMsg << std::endl;
        sqlite3_free(errMsg);
        sqlite3_close(db);
        return -1;
    } else {
        // 检查实际更新的行数
        // sqlite3_changes是一个C函数，返回最近一次修改操作影响的行数
        int changedRows = 0;
        std::string countSql = "SELECT changes()"; // 使用SQLite的内置changes()函数
        sqlite3_stmt *countStmt;
        if (sqlite3_prepare_v2(db, countSql.c_str(), -1, &countStmt, 0) == SQLITE_OK) {
            if (sqlite3_step(countStmt) == SQLITE_ROW) {
                changedRows = sqlite3_column_int(countStmt, 0);
            }
            sqlite3_finalize(countStmt);
        }
        
        if (changedRows == 0) {
            std::cerr << "警告: 没有记录被修改" << std::endl;
        }
    }
    
    std::cout << "已更新: 地点 " << placeId << " 的热度更新为 " << newPopularity << std::endl;
    
    // 关闭数据库
    sqlite3_close(db);
    return newPopularity;
}

// 设置API路由
void setupRoutes(crow::SimpleApp& app) {
    // 注意: /api/increase_popularity/<int> 路由已从这里移除
    // 因为它已经在MapService::setupMapRoutes函数中定义
    // 在两个地方定义相同的路由会导致错误:
    // "Server error: handler already exists for /api/increase_popularity/<int>"

    // 获取所有地点的API
    CROW_ROUTE(app, "/api/all_places")
    .methods("GET"_method)
    ([]() {
        sqlite3 *db;
        char *errMsg = 0;
        int rc;
        std::string result = "{\"places\":[";
        
        rc = sqlite3_open("tour_system.db", &db);
        if (rc) {
            return crow::response(500, "{\"error\": \"无法打开数据库\"}");
        }
        
        sqlite3_stmt *stmt;
        rc = sqlite3_prepare_v2(db, "SELECT id, name, type, latitude, longitude, popularity, rating, description, address FROM places", -1, &stmt, 0);
        
        if (rc != SQLITE_OK) {
            sqlite3_close(db);
            return crow::response(500, "{\"error\": \"SQL准备错误\"}");
        }
        
        bool first = true;
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            if (!first) {
                result += ",";
            }
            first = false;
            
            int id = sqlite3_column_int(stmt, 0);
            const char* name = (const char*)sqlite3_column_text(stmt, 1);
            const char* type = (const char*)sqlite3_column_text(stmt, 2);
            double lat = sqlite3_column_double(stmt, 3);
            double lng = sqlite3_column_double(stmt, 4);
            int popularity = sqlite3_column_int(stmt, 5);
            double rating = sqlite3_column_double(stmt, 6);
            const char* description = (const char*)sqlite3_column_text(stmt, 7);
            const char* address = (const char*)sqlite3_column_text(stmt, 8);
            
            result += "{\"id\":" + std::to_string(id) + 
                     ",\"name\":\"" + std::string(name ? name : "") + 
                     "\",\"type\":\"" + std::string(type ? type : "") + 
                     "\",\"latitude\":" + std::to_string(lat) + 
                     ",\"longitude\":" + std::to_string(lng) + 
                     ",\"popularity\":" + std::to_string(popularity) + 
                     ",\"rating\":" + std::to_string(rating);
                     
            if (description) {
                result += ",\"description\":\"" + std::string(description) + "\"";
            } else {
                result += ",\"description\":\"\"";
            }
            
            if (address) {
                result += ",\"address\":\"" + std::string(address) + "\"";
            } else {
                result += ",\"address\":\"\"";
            }
            
            result += "}";
        }
        
        sqlite3_finalize(stmt);
        sqlite3_close(db);
        
        result += "]}";
        return crow::response(200, result);
    });

    // 添加用户状态检查API
    CROW_ROUTE(app, "/api/user/status")
    .methods("GET"_method)
    ([]() {
        int user_id = get_current_user_id();
        if (user_id > 0) {
            // 用户已登录
            crow::json::wvalue result;
            result["status"] = "logged_in";
            result["user_id"] = user_id;
            return crow::response(200, result);
        } else {
            // 用户未登录
            crow::json::wvalue result;
            result["status"] = "not_logged_in";
            result["error"] = "未登录";
            return crow::response(401, result);
        }
    });
}

// 设置静态文件处理器路由
void setupStaticFileHandler(crow::SimpleApp& app, const std::string& publicDir = "public") {
    CROW_ROUTE(app, "/static_files/<path>")
    ([publicDir](const crow::request& req, std::string path) {
        std::string filepath = publicDir + "/" + path;
        std::string fileContent = readFile(filepath);
        
        if (fileContent.empty()) {
            return crow::response(404, "找不到文件");
        }
        
        // 设置MIME类型
        crow::response res(200, fileContent);
        
        std::string ext = filepath.substr(filepath.find_last_of("."));
        if (ext == ".html" || ext == ".htm") res.set_header("Content-Type", "text/html");
        else if (ext == ".css") res.set_header("Content-Type", "text/css");
        else if (ext == ".js") res.set_header("Content-Type", "application/javascript");
        else if (ext == ".json") res.set_header("Content-Type", "application/json");
        else if (ext == ".png") res.set_header("Content-Type", "image/png");
        else if (ext == ".jpg" || ext == ".jpeg") res.set_header("Content-Type", "image/jpeg");
        else if (ext == ".gif") res.set_header("Content-Type", "image/gif");
        else if (ext == ".svg") res.set_header("Content-Type", "image/svg+xml");
        else if (ext == ".ico") res.set_header("Content-Type", "image/x-icon");
        else res.set_header("Content-Type", "application/octet-stream");
        
        return res;
    });
    
    // 处理地图页面请求
    CROW_ROUTE(app, "/tour_map")
    ([]() {
        std::string filepath = "public/map.html";
        std::string fileContent = readFile(filepath);
        
        if (fileContent.empty()) {
            return crow::response(404, "找不到地图页面");
        }
        
        // 设置MIME类型
        crow::response res(200, fileContent);
        res.set_header("Content-Type", "text/html");
        return res;
    });
}

int main() {
    // 设置控制台输出编码为 UTF-8
    SetConsoleOutputCP(CP_UTF8);
    SetConsoleCP(CP_UTF8);
    
    std::cout << "启动个性化旅游系统..." << std::endl;
    
    try {
        // 初始化CURL
        if (!curl_wrapper::initialize()) {
            std::cerr << "CURL初始化失败!" << std::endl;
            return 1;
        }
        
        std::cout << "创建Web应用..." << std::endl;
        crow::SimpleApp app;
        std::cout << "Web应用创建完成。" << std::endl;

        // 加载HTML模板文件
        {
            std::ifstream loginFile("html/login.html");
            std::stringstream buffer;
            buffer << loginFile.rdbuf();
            pageTemplates["login_page"] = buffer.str();
        }
        
        {
            std::ifstream registerFile("html/register.html");
            std::stringstream buffer;
            buffer << registerFile.rdbuf();
            pageTemplates["register_page"] = buffer.str();
        }
        
        {
            std::ifstream indexFile("html/index.html");
            std::stringstream buffer;
            buffer << indexFile.rdbuf();
            pageTemplates["index_page"] = buffer.str();
        }
        
        {
            std::ifstream dashboardFile("html/dashboard.html");
            std::stringstream buffer;
            buffer << dashboardFile.rdbuf();
            pageTemplates["dashboard_page"] = buffer.str();
        }
        
        {
            std::ifstream pkuMapFile("html/pku_map.html");
            std::stringstream buffer;
            buffer << pkuMapFile.rdbuf();
            pageTemplates["pku_map_page"] = buffer.str();
        }
        
        {
            std::ifstream networkEditorFile("html/network_editor.html");
            std::stringstream buffer;
            buffer << networkEditorFile.rdbuf();
            pageTemplates["network_editor_page"] = buffer.str();
        }

        {
            std::ifstream travelLogsFile("html/travel_logs.html");
            std::stringstream buffer;
            buffer << travelLogsFile.rdbuf();
            pageTemplates["travel_logs_page"] = buffer.str();
        }

        {
            std::ifstream postFile("html/post.html");
            std::stringstream buffer;
            buffer << postFile.rdbuf();
            pageTemplates["post_page"] = buffer.str();
        }

        // 创建地图服务实例，使用您的百度地图API密钥
        // 注意：路线规划功能需要单独授权，请确保您的API密钥有足够的权限
        // 如果您的API密钥无效或缺少权限，请访问百度地图开放平台 (https://lbsyun.baidu.com/) 申请新密钥
        // 服务端应使用Web API密钥，而不是JS API密钥
        std::string baiduMapApiKey = "YWYhzv8agmWHMH3YXoHBAJIIDQfiUAzY"; // Web API密钥
        MapService mapService(app, "tour_system.db");
        
        // 创建数据库连接
        Database db("tour_system.db");
        
        // 创建地点数据库连接
        PlaceDB placeDb(db);
        
        // 首页路由
        CROW_ROUTE(app, "/")
        ([&](const crow::request& req) {
            return crow::response(pageTemplates["index_page"]);
        });

        CROW_ROUTE(app, "/login.html")
        ([&](const crow::request& req) {
            return crow::response(pageTemplates["login_page"]);
        });

        CROW_ROUTE(app, "/register.html")
        ([&](const crow::request& req) {
            return crow::response(pageTemplates["register_page"]);
        });

        CROW_ROUTE(app, "/dashboard.html")
        ([&](const crow::request& req) {
            return crow::response(pageTemplates["dashboard_page"]);
        });

        CROW_ROUTE(app, "/pku_map.html")
        ([&](const crow::request& req) {
            return crow::response(pageTemplates["pku_map_page"]);
        });

        CROW_ROUTE(app, "/network_editor.html")
        ([&](const crow::request& req) {
            return crow::response(pageTemplates["network_editor_page"]);
        });

        CROW_ROUTE(app, "/travel_logs.html")
        ([&](const crow::request& req) {
            return crow::response(pageTemplates["travel_logs_page"]);
        });

        // 地图页面路由
        CROW_ROUTE(app, "/map")
        ([&mapService]() {
            return mapService.getMapPage();
        });
        
        // 注册地图相关API路由
        try {
            MapService::setupMapRoutes(app, mapService, placeDb);
            // 设置路由API端点
            mapService.setupRoutes();
        } catch(const std::exception& e) {
            std::cerr << "设置地图路由错误: " << e.what() << std::endl;
        }
        
        // 注册登录相关路由
        LoginInterface::setupLoginRoutes(app, db);

        // 注册日记相关路由
        DiaryInterface::setupDiaryRoutes(app, db);

        // 设置静态文件服务
        CROW_ROUTE(app, "/html/<path>")
        ([](const std::string& path) {
            std::string filePath = "html/" + path;
            std::ifstream file(filePath.c_str(), std::ios::in);
            if (!file) {
                return crow::response(404);
            }
            
            std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
            
            crow::response res(content);
            
            if (ends_with(path, ".html")) res.set_header("Content-Type", "text/html");
            else if (ends_with(path, ".css")) res.set_header("Content-Type", "text/css");
            else if (ends_with(path, ".js")) res.set_header("Content-Type", "application/javascript");
            else if (ends_with(path, ".png")) res.set_header("Content-Type", "image/png");
            else if (ends_with(path, ".jpg") || ends_with(path, ".jpeg")) res.set_header("Content-Type", "image/jpeg");
            
            return res;
        });
          
        // 设置API路由
        setupRoutes(app);

        // 设置静态文件处理器
        setupStaticFileHandler(app, "public");

        std::cout << "启动服务器，监听所有网络接口，端口：8080..." << std::endl;
        
        // 使用扩展库方法启动服务器
        crow_ext::start_server(app, 8080);
        
        std::cout << "服务器已关闭" << std::endl;
        
        // 清理CURL资源
        curl_wrapper::cleanup();
    }
    catch (const std::exception& e) {
        std::cerr << "发生异常: " << e.what() << std::endl;
        curl_wrapper::cleanup();
        return 1;
    }
    catch (...) {
        std::cerr << "发生未知异常" << std::endl;
        curl_wrapper::cleanup();
        return 1;
    }

    return 0;
}
